#pragma once
#ifndef __G_MODULE_MANAGER_H__
#define __G_MODULE_MANAGER_H__

#include <string>
#include <unordered_map>

#include "GTypes.h"
#include "Gsingleton.h"
#include "GInitializable.h"

namespace GEngine
{
	class GModule;
	class GModuleDescriptor;
	class GDynamicLibrary;

	class GModuleManager : public GUtil::GInitializable, public GUtil::GSingleton<GModuleManager>
	{
	friend class GUtil::GSingleton<GModuleManager>;

	typedef std::unordered_map<std::string, GDynamicLibrary*> LibraryMap;
	typedef std::unordered_map<std::string, GModuleDescriptor*> DescriptorMap;
	
	private:
		LibraryMap				Libraries;
		DescriptorMap			Descriptors;

								GModuleManager();
								~GModuleManager();

		bool					LoadLibraries(const char* FolderPath);
		void					UnloadLibraries();

	public:
		bool					LoadLibrary(const char* Path);
		void					UnloadLibrary(const char* Path);

		bool					RegisterModule(GModuleDescriptor* Descriptor);
		void					UnregisterModule(GModuleDescriptor* Descriptor);

		GModule*				CreateModule(const char* ModuleName);
		
		GModuleDescriptor*		GetDescriptor(const char* ModuleName);
		
		const char*				GetImplementation(const char* InterfaceName, GSize Index);
		GUInt32					GetImplementationCount(const char* InterfaceName);

		bool					Initialize() OVERRIDE;
		void					Uninitialize() OVERRIDE;
	};
}

#define mGModuleManager		GEngine::GModuleManager::GetInstance()

#endif